package com.zhou.base.components.log.trace.log;


import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE;

/**
 * @author xianfeng
 * @date 2023/5/13 18:20
 */
@Slf4j
@Aspect
@Order(HIGHEST_PRECEDENCE)
public class RequestLog {
    @Pointcut("execution(public * com..controller..*.*(..))*")
    public void anyController() {
    }

    @Around("anyController()")
    private Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 请求URL
        Object result = null;
        Long startTime = System.currentTimeMillis();
        try {
            requestURI();
            // 请求参数
            List<Object> args = Arrays.asList(joinPoint.getArgs());
            args = args.stream().filter(t -> !(t instanceof ServletResponse))
                    .filter(t -> !(t instanceof ServletRequest))
                    .collect(Collectors.toList());
            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
            // 类路径URL
            String methodPackage = methodSignature.getDeclaringTypeName();
            // 方法名
            String method = methodSignature.getMethod().getName();
            StringBuilder builder = new StringBuilder();
            builder.append(methodPackage)
                    .append(".")
                    .append(method)
                    .append("，请求参数：")
                    .append(JSONUtil.toJsonStr(args));
            log.debug(builder.toString());
            result = joinPoint.proceed();
        } finally {
            Object myResult = result;
            if (result == null) {
                myResult = "void";
            }
            if (result instanceof byte[]) {
                myResult = "byte[]";
            }
            log.debug("耗时={}ms,响应结果:{}", System.currentTimeMillis() - startTime, StrUtil.sub(JSONUtil.toJsonStr(myResult), 0, 3000));
        }
        return result;
    }


    /**
     * 打印请求URL
     */
    private void requestURI() {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String requestURL = request.getRequestURI();
        log.debug(String.format("请求URL：%s", requestURL));
    }

}